import junit.framework.Assert;

import org.junit.Test;

/**
 * JUnit tester class
 * 
 * @author Jovan Munroe
 */

public class TicTacToeBoardTest
{
	/**
	 * Ensure the constructor sets all spaces to blanks
	 */
	@Test
	public void testConstructor()
	{
		TicTacToeBoard board = new TicTacToeBoard();
		for (int row = 0; row < 3; row++) {
			for (int col = 0; col < 3; col++)
			{
				char actual = board.get(row, col);
				char expected = ' ';
				Assert.assertEquals(expected, actual);
			}
		}
	}

	/**
	 * Ensure the second constructor sets all spaces to blanks
	 */
	@Test
	public void testConstructor2()
	{
		//default
		TicTacToeBoard board = new TicTacToeBoard(5);
		for (int row = 0; row < 5; row++) {
			for (int col = 0; col < 5; col++)
			{
				char actual = board.get(row, col);
				char expected = ' ';
				Assert.assertEquals(expected, actual);
			}
		}
	}

	/**
	 * Ensure the second constructor set board for negative input
	 */
	@Test
	public void testConstructor3()
	{
		//negative board
		TicTacToeBoard board = new TicTacToeBoard(-10);
		for (int row = 0; row < 3; row++) {
			for (int col = 0; col < 3; col++)
			{
				char actual = board.get(row, col);
				char expected = ' ';
				Assert.assertEquals(expected, actual);
			}
		}
	}


	/**
	 * Ensure the set method works.
	 */
	@Test
	public void testSet()
	{
		TicTacToeBoard board = new TicTacToeBoard();
		board.set(1, 1, 'X');
		board.set(0, 0, 'Y');
		board.set(2, 2, 'Z');
		char expected = 'X';
		char actual = board.get(1,1);
		Assert.assertEquals(expected, actual);
		expected = 'Y';
		actual = board.get(0,0);
		Assert.assertEquals(expected, actual);
		expected = 'Z';
		actual = board.get(2,2);
		Assert.assertEquals(expected, actual);

		//out of bounds - returns false
		board.set(5,5, 'X');
		board.set(-10,-10, 'X');

		//tries to overwrite - returns false
		board.set(1,1,'O');
	}

	/**
	 * Ensure the get method works.
	 */
	@Test
	public void testGet()
	{
		TicTacToeBoard board = new TicTacToeBoard();
		board.set(1, 1, 'X');
		board.set(0, 0, 'Y');
		board.set(2, 2, 'Z');
		char expected = 'X';
		char actual = board.get(1,1);
		Assert.assertEquals(expected, actual);
		expected = 'Y';
		actual = board.get(0,0);
		Assert.assertEquals(expected, actual);
		expected = 'Z';
		actual = board.get(2,2);
		Assert.assertEquals(expected, actual);

		//out of bounds - expect default char;
		expected = ' ';
		actual = board.get(5,5);
		Assert.assertEquals(expected, actual);
		actual = board.get(-5,-5);
		Assert.assertEquals(expected, actual);
	}

	/**
	 * Ensure the toString method works.
	 */
	@Test
	public void testtoString()
	{
		//default
		TicTacToeBoard board = new TicTacToeBoard();
		System.out.println(board.toString());
		//dimension equal 5
		TicTacToeBoard board2 = new TicTacToeBoard(5);
		System.out.println(board2.toString());
		//dimension changes to 3
		TicTacToeBoard board3 = new TicTacToeBoard(-5);
		System.out.println(board3.toString());
	}

	/**
	 * Ensure the hasHorizontalWin method works.
	 */
	@Test
	public void testHorizontalWin()
	{
		//horizontal win test for 4x4 tic tac toe
		TicTacToeBoard board = new TicTacToeBoard(4);
		board.set(0, 0, 'X');
		board.set(0, 1, 'X');
		board.set(0, 2, 'X');
		board.set(0, 3, 'X');
		System.out.println(board);
		System.out.println("Horizontal Win: "+board.hasHorizontalWin('X'));
		boolean expected = true;
		boolean actual = board.hasHorizontalWin('X');
		Assert.assertEquals(expected, actual);

		//horizontal win test
		TicTacToeBoard board2 = new TicTacToeBoard(-10);
		board2.set(2, 0, 'i');
		board2.set(2, 1, 'i');
		board2.set(2, 2, 'i');
		System.out.println(board2);
		System.out.println("Horizontal Win: "+board2.hasHorizontalWin('i'));
		expected = true;
		actual = board2.hasHorizontalWin('i');
		Assert.assertEquals(expected, actual);
	}

	/**
	 * Ensure the hasVerticalWin method works.
	 */
	@Test
	public void testVerticalWin()
	{
		//vertical win test for 4x4 tic tac toe
		TicTacToeBoard board = new TicTacToeBoard(4);
		board.set(0, 0, 'X');
		board.set(1, 0, 'X');
		board.set(2, 0, 'X');
		board.set(3, 0, 'X');
		System.out.println(board);
		System.out.println("Vertical Win: "+board.hasVerticalWin('X'));
		boolean expected = true;
		boolean actual = board.hasVerticalWin('X');
		Assert.assertEquals(expected, actual);

		//vertical win test
		TicTacToeBoard board2 = new TicTacToeBoard(-10);
		board2.set(0, 1, 'i');
		board2.set(1, 1, 'i');
		board2.set(2, 1, 'i');
		System.out.println(board2);
		System.out.println("Vertical Win: "+board2.hasVerticalWin('i'));
		expected = true;
		actual = board2.hasVerticalWin('i');
		Assert.assertEquals(expected, actual);
	}

	/**
	 * Ensure the hasDiagonalWin method works.
	 */
	@Test
	public void testDiagonalWin()
	{
		//Diagonal \ win test for 4x4 tic tac toe
		TicTacToeBoard board = new TicTacToeBoard(4);
		board.set(0, 0, 'X');
		board.set(1, 1, 'X');
		board.set(2, 2, 'X');
		board.set(3, 3, 'X');
		System.out.println(board);
		System.out.println("Diagonal Win: "+board.hasDiagonalWin('X'));
		boolean expected = true;
		boolean actual = board.hasDiagonalWin('X');
		Assert.assertEquals(expected, actual);

		//Diagonal / win test
		TicTacToeBoard board2 = new TicTacToeBoard(-10);
		board2.set(2, 0, 'i');
		board2.set(1, 1, 'i');
		board2.set(0, 2, 'i');
		System.out.println(board2);
		System.out.println("Diagonal Win: "+board2.hasDiagonalWin('i'));
		expected = true;
		actual = board2.hasDiagonalWin('i');
		Assert.assertEquals(expected, actual);
	}
	/**
	 * Ensures hasWin method works
	 */
	@Test
	public void testWin()
	{
		//Diagonal \ win test for 4x4 tic tac toe
		TicTacToeBoard board = new TicTacToeBoard(4);
		board.set(0, 0, 'X');
		board.set(1, 1, 'X');
		board.set(2, 2, 'X');
		board.set(3, 3, 'X');
		board.set(0,0,'O');
		board.set(0,1,'O');
		board.set(0,2,'O');
		board.set(0,3,'O');
		System.out.println(board);
		System.out.println("X Has Win: "+board.hasWin('X'));
		boolean expected = true;
		boolean actual = board.hasWin('X');
		Assert.assertEquals(expected, actual);
		System.out.println("O Has Win: "+board.hasWin('O'));
		expected = false;
		actual = board.hasWin('O');
		Assert.assertEquals(expected, actual);
	}
}
